home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / snpd1292.zip / EDITGETS.C < prev    next >
C/C++ Source or Header  |  1992-12-26  |  12KB  |  349 lines

  1. /* editgets.c - line input w/editing                                        */
  2. /* this code is released to the public domain                               */
  3. /* written by Jon Burchmore                                                 */
  4. /* modifications & enhancements by Bob Stout                                */
  5.  
  6. /* This is as close to ANSI compliant C that I could come, but it was made  */
  7. /* on an IBM compatable computer, so I designed it for that platform.       */
  8. /* If you're porting it to another computer type, please note how the IBM   */
  9. /* passes enhanced keys.  First, it sends an ASCIIZ (character 0), then a   */
  10. /* standard character.  Anyway, what the switch() statement does is check   */
  11. /* to see if there WAS a zero sent, and if there wasn't, it just "falls"    */
  12. /* through to the default, which handles normal characters.                 */
  13.  
  14. /* The conio header file provides the getch() function, which returns a     */
  15. /* single character from the KEYBOARD, not stdin, and waits if it must.     */
  16. /* It is be possible to re-write this function for a computer besides an    */
  17. /* IBM PC.                                                                  */
  18.  
  19. /* It would be possible to check the variable insert, and if it's on, make  */
  20. /* the cursor large, and if it's off, make the cursor small, but my primary */
  21. /* goal is portability, not fancy add-ons                                   */
  22.  
  23. /* Pardon the lack of comments.  I'm a coder, not an author.  Besides, if   */
  24. /* you can't understand this, DON'T USE IT! (Words to live by)              */
  25.  
  26. #include <conio.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30.  
  31. #define ESC     0x1B
  32. #define LEFT    0x4B
  33. #define RIGHT   0x4D
  34. #define HOME    0x47
  35. #define END     0x4F
  36. #define INSERT  0x52
  37. #define DELETE  0x53
  38. #define BACKSPC 0x08
  39. #define ENTER   0x0D
  40. #define CTLEND  0x75
  41. #define CTLHOME 0x77
  42. #define CTLRT   0x74
  43. #define CTLLFT  0x73
  44.  
  45. /*
  46. **  Password mode - '*' is echoed for all characters, only ESC, ENTER,
  47. **  BACKSPC, and CTLHOME are active.
  48. */
  49.  
  50. int password_mode = 0;
  51.  
  52. int jgets(char *s, int maxlen)
  53. {
  54.       char temp[500];
  55.       int insert = 1, done = 0, pos = 0, len = 0, i, j, c, zeroflag;
  56.  
  57.       for (i = 0; i < maxlen; ++i)
  58.             putchar('_');
  59.       for (i = 0; i < maxlen; ++i)
  60.             putchar(BACKSPC);
  61.       while (!done)
  62.       {
  63.             zeroflag = 0;
  64.             if ((c = getch()) == 0)
  65.             {
  66.                   zeroflag = 1;
  67.                   c = getch();
  68.             }
  69.             switch (c)
  70.             {
  71.             case ESC :
  72.                   if (len == 0)
  73.                         break;
  74.                   if (pos != len)
  75.                   {
  76.                         for (i = pos; i < len; i++)
  77.                               putch('_');
  78.                         for (i = len; i >= 0; i--)
  79.                         {
  80.                               putch(BACKSPC);
  81.                               putch('_');
  82.                               putch(BACKSPC);
  83.                         }
  84.                         pos = len = 0;
  85.                         break;
  86.                   }
  87.  
  88.             case LEFT :
  89.                   if (zeroflag)
  90.                   {
  91.                         if (password_mode)
  92.                               break;
  93.                         if (pos == 0)
  94.                               break;
  95.                         pos--;
  96.                         putch(BACKSPC);
  97.                         break;
  98.                   }
  99.  
  100.             case RIGHT :
  101.                   if (zeroflag)
  102.                   {
  103.                         if (password_mode)
  104.                               break;
  105.                         if (pos == len)
  106.                               break;
  107.                         if (pos != maxlen)
  108.                         {
  109.                               putch(temp[pos]);
  110.                               pos++;
  111.                         }
  112.                         break;
  113.                   }
  114.  
  115.             case HOME :
  116.                   if (zeroflag)
  117.                   {
  118.                         if (password_mode)
  119.                               break;
  120.                         while (pos-- > 0)
  121.                               putch(BACKSPC);
  122.                         pos = 0;
  123.                         break;
  124.                   }
  125.  
  126.             case END :
  127.                   if (zeroflag)
  128.                   {
  129.                         if (password_mode)
  130.                               break;
  131.                         while (pos < len)
  132.                               putch(temp[pos++]);
  133.                         break;
  134.                   }
  135.  
  136.             case INSERT :
  137.                   if (zeroflag)
  138.                   {
  139.                         if (password_mode)
  140.                               break;
  141.                         insert = (!(insert));
  142.                         break;
  143.                   }
  144.  
  145.             case DELETE :
  146.                   if (zeroflag)
  147.                   {
  148.                         if (password_mode)
  149.                               break;
  150.                         if (pos == len)
  151.                               break;
  152.                         for (i = pos; i < len; i++)
  153.                               temp[i] = temp[i + 1];
  154.                         len--;
  155.                         for (i = pos; i < len; i++)
  156.                               putch(temp[i]);
  157.                         putch('_');
  158.                         for (i = len + 1; i > pos; i--)
  159.                               putch(BACKSPC);
  160.                         break;
  161.                   }
  162.  
  163.             case BACKSPC :
  164.                   if (c == BACKSPC)
  165.                   {
  166.                         if (pos == 0)
  167.                               break;
  168.                         if (pos != len)
  169.                         {
  170.                               for (i = pos - 1; i < len; i++)
  171.                                     temp[i] = temp[i + 1];
  172.                               pos--;
  173.                               len--;
  174.                               putch(BACKSPC);
  175.                               for (i = pos; i < len; i++)
  176.                                     putch(temp[i]);
  177.                               putch('_');
  178.                               for (i = len; i >= pos; i--)
  179.                                     putch(BACKSPC);
  180.                         }
  181.                         else
  182.                         {
  183.                               putch(BACKSPC);
  184.                               putch('_');
  185.                               putch(BACKSPC);
  186.                               pos = --len;
  187.                         }
  188.                         break;
  189.                   }
  190.  
  191.             case ENTER :
  192.                   if (c == ENTER)
  193.                   {
  194.                         done = 1;
  195.                         break;
  196.                   }
  197.  
  198.             case CTLEND :
  199.                   if (zeroflag)
  200.                   {
  201.                         if (password_mode)
  202.                               break;
  203.                         for (i = pos; i < len; ++i)
  204.                               putch('_');
  205.                         for (i = pos; i < len; ++i)
  206.                               putch(BACKSPC);
  207.                         len = pos;
  208.                         break;
  209.                   }
  210.  
  211.             case CTLHOME :
  212.                   if (zeroflag)
  213.                   {
  214.                         if (pos == 0)
  215.                               break;
  216.                         if (pos != len)
  217.                         {
  218.                               while (0 != pos)
  219.                               {
  220.                                     for (i = pos - 1; i < len; i++)
  221.                                           temp[i] = temp[i + 1];
  222.                                     pos--;
  223.                                     len--;
  224.                                     putch(BACKSPC);
  225.                                     for (i = pos; i < len; i++)
  226.                                           putch(temp[i]);
  227.                                     putch('_');
  228.                                     for (i = len; i >= pos; i--)
  229.                                           putch(BACKSPC);
  230.                               }
  231.                         }
  232.                         else
  233.                         {
  234.                               while (0 != pos)
  235.                               {
  236.                                     putch(BACKSPC);
  237.                                     putch('_');
  238.                                     putch(BACKSPC);
  239.                                     pos = --len;
  240.                               }
  241.                         }
  242.                         break;
  243.                   }
  244.  
  245.             case CTLRT :
  246.                   if (zeroflag)
  247.                   {
  248.                         if (password_mode)
  249.                               break;
  250.                         do
  251.                         {
  252.                               if (pos == len)
  253.                                     break;
  254.                               if (pos != maxlen)
  255.                               {
  256.                                     putch(temp[pos]);
  257.                                     pos++;
  258.                               }
  259.                         } while (isspace(temp[pos]));
  260.                         do
  261.                         {
  262.                               if (pos == len)
  263.                                     break;
  264.                               if (pos != maxlen)
  265.                               {
  266.                                     putch(temp[pos]);
  267.                                     pos++;
  268.                               }
  269.                         } while (!isspace(temp[pos]));
  270.                         break;
  271.                   }
  272.  
  273.             case CTLLFT :
  274.                   if (zeroflag)
  275.                   {
  276.                         if (password_mode)
  277.                               break;
  278.                         do
  279.                         {
  280.                               if (pos == 0)
  281.                                     break;
  282.                               pos--;
  283.                               putch(BACKSPC);
  284.                         } while (isspace(temp[pos]));
  285.                         do
  286.                         {
  287.                               if (pos == 0)
  288.                                     break;
  289.                               pos--;
  290.                               putch(BACKSPC);
  291.                         } while (!isspace(temp[pos]));
  292.                         break;
  293.                   }
  294.  
  295.             default :
  296.                   if (zeroflag)
  297.                         break;
  298.                   if (c == 0 || pos == maxlen)
  299.                         break;
  300.                   if ((!(insert)) || pos == len)
  301.                   {
  302.                         temp[pos++] = c;
  303.                         if (pos > len) len++;
  304.                         if (password_mode)
  305.                               putch('*');
  306.                         else  putch(c);
  307.                   }
  308.                   else
  309.                   {
  310.                         for (i = len++; i >= pos; i--)
  311.                               temp[i + 1] = temp[i];
  312.                         temp[pos++] = c;
  313.                         if (password_mode)
  314.                               putch('*');
  315.                         else  putch(c);
  316.                         for (i = pos; i < len; i++)
  317.                               putch(temp[i]);
  318.                         for (i = len; i > pos; i--)
  319.                               putch(BACKSPC);
  320.                   }
  321.             }
  322.       }
  323.       temp[len] = '\0';
  324.       strcpy(s, temp);
  325.       return len;
  326. }
  327.  
  328. #ifdef TEST
  329.  
  330. int main(void)
  331. {
  332.       char mystring[60];
  333.  
  334.       memset(mystring, 0, 60);
  335.       fputs("Enter any string: ", stdout);
  336.       jgets(mystring, 60);
  337.       puts("");
  338.       printf("jgets() returned:\n%s\n", mystring);
  339.  
  340.       password_mode = 1;
  341.       memset(mystring, 0, 60);
  342.       fputs("Enter any password: ", stdout);
  343.       jgets(mystring, 50);
  344.       puts("");
  345.       printf("jgets() returned:\n%s\n", mystring);
  346. }
  347.  
  348. #endif
  349.